import store from '@/store';
import router from '@/router';
import { getCookie } from './cache'
import moment from 'moment'
import i18n from "@/lang/index.js";
import * as api from "@/api/index.js";
import { ElMessage } from 'element-plus'
/**
 * 权限匹配
 * @param {*} idsArray  权限标识数组
 */
export function hasPermi(idsArray = []) {
  const all_permission = "*:*:*";
  const permissions = store.state.user.permissions;
  const permissionFlag = idsArray;
  return permissions.some((permission) => {
    return all_permission === permission || permissionFlag.includes(permission);
  });
}

// /**
//  * 构造树型结构数据
//  * @param {*} data 数据源
//  * @param {*} id id字段 默认 'id'
//  * @param {*} parentId 父节点字段 默认 'parentId'
//  * @param {*} children 孩子节点字段 默认 'children'
//  * @param {*} rootId 根Id 默认 0
//  */

export const handleTree = (
  data,
  id,
  parentId,
  children,
  rootId
) => {
  id = id || "id";
  parentId = parentId || "parentId";
  children = children || "children";
  rootId = rootId || 0;
  // 对源数据深度克隆
  const cloneData = JSON.parse(JSON.stringify(data));
  // 循环所有项
  const treeData = cloneData.filter((father) => {
    const branchArr = cloneData.filter((child) => {
      // 返回每一项的子级数组
      return father[id] === child[parentId];
    });
    branchArr.length > 0 ? (father.children = branchArr) : "";
    // 返回第一层
    return father[parentId] === rootId;
  });
  return treeData !== "" ? treeData : data;
};


/**
* 通过key值拿到对应的Name
* @param {Array} array  数组数据
* @param {String} keyVal  code值
* @param {String} key  数组code的参数名，默认是id
* @param {String} val  数组name的参数名，默认是value
*/
export function matchValue(
  array = [],
  keyVal,
  key = "id",
  val = "value"
) {
  if (!keyVal || !array.length) {
    return "";
  }
  const matchObj = array.find((item) => item[key] === keyVal);
  let a = "";
  if (matchObj) {
    a = matchObj[val];
  }
  return a;
}


/**
* 设置弹框内表格高度
* @param {*} cusHeight 自定义高度
*/
export function setDialogTableHeight(cusHeight = 0) {
  const mspace = 5; // 标签
  const contentDom = document.querySelector(".my-dialog-body"); // 弹窗内容
  const conditionFormDom = document.querySelector(
    ".my-dialog-body .condition-form"
  ); // 条件筛选
  const buttonRowsDom = document.querySelector(
    ".my-dialog-body .con-button-rows"
  ); // 行内按钮
  const footerDom = document.querySelector(
    ".my-dialog-body .el-dialog__footer"
  );
  const contentDomHeight = contentDom?.offsetHeight || 0;
  const filterHeight = conditionFormDom
    ? conditionFormDom.offsetHeight + mspace
    : 0;
  const buttonRowsHeight = buttonRowsDom
    ? buttonRowsDom.offsetHeight + mspace
    : 0;
  const footerDomHeight = footerDom ? footerDom.offsetHeight + mspace : 0;
  const comHeight =
    filterHeight + buttonRowsHeight + cusHeight + footerDomHeight + mspace * 4;
  return contentDomHeight - comHeight - 160;
}


/**
 * 设置表格高度
 *
 */
export function setTableHeight() {
  const contentDom = document.querySelector(".menu_right"); // 右侧内容
  const conditionFormDom = document.querySelector(
    ".condition-form"
  ); // 条件筛选
  const buttonRowsDom = document.querySelector(
    ".con-button-rows"
  ); // 行内按钮
  const pagerDom = document.querySelector(".vxe-pager"); // 列表页码
  const contentDomHeight = contentDom ? contentDom.offsetHeight : 0;
  const filterHeight = conditionFormDom ? conditionFormDom.offsetHeight : 0;
  const buttonRowsHeight = buttonRowsDom ? buttonRowsDom.offsetHeight : 0;
  const pagerHeight = pagerDom ? pagerDom?.offsetHeight : 0;
  const comHeight = filterHeight + buttonRowsHeight;
  return contentDomHeight - comHeight - pagerHeight;
}


/**
 * 防抖函数
 * @param { (...args: any[]) => any} func 要执行的函数
 * @param {number} wait 等待时间（毫秒）
 * @param {boolean} immediate 是否立即执行
 * @returns { (...args: any[]) => any} 返回一个新的函数
 */
export function debounce(func, wait, immediate) {
  if (wait === void 0) { wait = 500; }
  if (immediate === void 0) { immediate = false; }
  var timeout;
  return function () {
    var context = this;
    var args = arguments;
    var later = function () {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
}


// export function columnFilters(arr, keys) {
//   let rows = {};
//   try {
//     arr.forEach((item) => {
//       if (item?.structure) {
//         rows = columnFilters(item.structure, keys);
//         throw new Error();
//       }
//       const flag = item.content.find((o) => o.prop === keys);
//       if (flag) {
//         rows = flag;
//         throw new Error();
//       }
//     });
//   } catch (e) {
//     return rows;
//   }
// }

export function columnFilters(arr, keys) {
  let rows = {};
  try {
    arr.forEach((item) => {
      const contents = item?.structure || item.content || item.columns || [] 
      const flag = contents.find((o) => o?.prop === keys || o?.field === keys);
      if (flag) {
       
        rows = flag;
        throw new Error();
      } else {
        if (item?.structure || item.content || item?.columns ) {
          rows = columnFilters(item.structure || item.content|| item?.columns || [], keys);
          if (rows) {
            throw new Error();
          }
        }
      }
    });
  } catch (e) {
    return rows;
  }
}

export function queryFormColumnFilters(arr, keys) {
  let rows = {}
  try {
    const flag = arr.find(o => o.prop === keys)
    if (flag) {
      rows = flag
      throw new Error()
    }
  } catch (e) {
    return rows
  }
}

export function tabelColumnFilters(arr, keys) {
  let rows = {}
  try {
    const flag = arr.find(o => o.field === keys)
    if (flag) {
      rows = flag
      throw new Error()
    }
  } catch (e) {
    return rows
  }
}

// 设置内容高度
export function setContentHeight(cusHeight = 0) {
  const contentDom = document.querySelector('.menu_content')
  const contentDomHeight = contentDom ? contentDom.offsetHeight : 0
  return (contentDomHeight - 10 - cusHeight) + 'px'
}



// 日期时区转换
export function formatterTimeZones(val, valueFormat = 'YYYY-MM-DD HH:mm:ss') {
  const timeZone = getCookie(import.meta.env.VITE_VUETIME_ZONE_STR)
  return val && timeZone ? moment(val).tz(timeZone).format(valueFormat) : val
}

export function getSubZhEn(code) {
  return new Promise((resolve, reject) => {
    const obj = {}
    api.default.system.basic
      .getSub(code)
      .then((res) => {
        for (const key in res.data) {
          const sub = res.data[key] ? res.data[key].map(item => {
            return {
              ...item,
              subName: i18n.global.t(item.subName || '')
            }
          }) : []
          obj[key] = sub
        }
        resolve(obj)
      });

  })

}

export function fileViewing(url, data, original) {
  try {
    // 如果有URL（已上传的文件），直接在新窗口打开
    if (url) {
      window.open(import.meta.env.VITE_VUEIMAGE_FILE_URL + url, "_blank");
      return;
    }

    // 如果有原始文件对象（本地文件），创建临时URL进行预览
    if (data) {
      const fileType = data.type;
      const previewableTypes = [
        "image/jpeg",
        "image/png",
        "image/gif",
        "image/webp",
        "application/pdf",
        "text/plain",
        "application/vnd.ms-excel",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "application/msword",
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      ];

      // 对于可预览的文件类型，尝试预览
      if (previewableTypes.includes(fileType)) {
        const objectUrl = URL.createObjectURL(data);
        window.open(objectUrl, "_blank");

        // 在组件销毁时释放URL，避免内存泄漏
        // 这里可以使用setTimeout在一定时间后释放，如果预览窗口已关闭
        setTimeout(() => {
          URL.revokeObjectURL(objectUrl);
        }, 60000); // 1分钟后释放
      } else {
        // 对于不可预览的文件，提示用户下载
        const a = document.createElement("a");
        a.href = URL.createObjectURL(data);
        a.download = original;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(a.href);
      }
      return;
    }

    // 如果既没有URL也没有原始文件，提示用户
    ElMessage.warning(i18n.global.t("无法查看文件：文件未上传或文件信息不完整"));
  } catch (error) {
    ElMessage.error(i18n.global.t("查看文件失败，请稍后重试"));
  }
}

/**
 * 计算两个日期之间相差的天数
 * @param {string|Date} date1 第一个日期
 * @param {string|Date} date2 第二个日期
 * @param {boolean} absolute 是否返回绝对值，默认为true
 * @returns {number} 相差的天数
 */
export function getDaysDiff(date1, date2, absolute = true) {
  if (!date1 || !date2) {
    return 0;
  }

  const moment1 = moment(date1);
  const moment2 = moment(date2);

  if (!moment1.isValid() || !moment2.isValid()) {
    return 0;
  }

  const diffDays = moment2.diff(moment1, 'days');
  return absolute ? Math.abs(diffDays) : diffDays;
}

/**
 * 生成船期描述
 * @param {string|Date} etdDate 预计离港日期(ETD)
 * @param {string|Date} cutoffTime 截单时间
 * @returns {string} 船期描述，格式如"3截6开"
 */
export function generateScheduleDescription(etdDate, cutoffTime) {
  if (!etdDate || !cutoffTime) {
    return '';
  }

  const etdMoment = moment(etdDate);
  const cutoffMoment = moment(cutoffTime);

  if (!etdMoment.isValid() || !cutoffMoment.isValid()) {
    return '';
  }

  // 获取截单时间的星期几（0=周日, 1=周一, ..., 6=周六）
  const cutoffDay = cutoffMoment.day();
  // 获取ETD的星期几
  const etdDay = etdMoment.day();

  // 将周日从0转为7，使其符合"周日=7"的习惯
  const cutoffDayNum = cutoffDay === 0 ? 7 : cutoffDay;
  const etdDayNum = etdDay === 0 ? 7 : etdDay;

  // 返回格式："周几截周几开"
  return `${cutoffDayNum}截${etdDayNum}开`;
}

/**
 * 格式化银行卡号显示
 * @param {string} cardNumber 银行卡号
 * @param {string} separator 分隔符，默认为空格
 * @param {number} groupSize 分组大小，默认为4位
 * @returns {string} 格式化后的银行卡号
 */
export function formatBankCard(cardNumber, separator = ' ', groupSize = 4) {
  if (!cardNumber) {
    return '';
  }

  // 移除所有非数字字符
  const cleaned = cardNumber.toString().replace(/\D/g, '');

  if (!cleaned) {
    return '';
  }

  // 将数字按指定分组大小分割
  const groups = [];
  for (let i = 0; i < cleaned.length; i += groupSize) {
    groups.push(cleaned.slice(i, i + groupSize));
  }

  // 用分隔符连接各分组
  return groups.join(separator);
}


/**
 * 关闭标签页
 * @param {String} fullPath 要关闭的标签页路径
 * @param {String} routerPath 当前路由路径
 */
export function closeTag(item, routerPath) {
window.history.back()
return
  // 获取store中的标签页数据
  const tagsViews = store.state.tagsView.visitedViews;
  // 创建一个简单的item对象用于delView操作
  if (tagsViews.length === 2) {
    router.push("/home/index");
    store.dispatch("delView", item);
    return;
  }
  const index = tagsViews.findIndex(
    (v) => v.fullPath === item.fullPath
  );
  let path = "";
  if (index === 1) {
    path = tagsViews[index + 1];
  } else {
    path = tagsViews[index - 1];
  }
  const str =
    path.path.split("/")[1] != "home" ? `/${path.path.split("/")[1]}` : "";
  if (str && store.state.permission.topRouterPath != str) {
    store.dispatch("ClickTopMenu", {
      path: str,
    });
  }
  store.dispatch("delView", item);
  router.push(path);
}

export function characterSegmentation(row,keys,separator = '/') {
  const arr = []
  keys.forEach(key => {
    row[key] && arr.push(row[key])
  })
  return arr.join(separator)
}
/**
 * 百分比计算
 * @param {number} value 数值
 * @param {number} total 总数
 * @param {number} decimals 小数位数，默认为2
 * @returns {string} 百分比字符串
 */
export function calculatePercentage(value, total, decimals = 2) {
  if (total === 0) return '0%';
  const percentage = multiply(divide(value, total), 100);
  return `${round(percentage, decimals)}%`;
}
/**
 * 浮点数加法，解决精度问题
 * @param {number} num1 第一个数字
 * @param {number} num2 第二个数字
 * @returns {number} 相加结果
 */
export function add(num1, num2) {
  const r1 = `${num1}`.split('.')[1]?.length || 0;
  const r2 = `${num2}`.split('.')[1]?.length || 0;
  const m = Math.pow(10, Math.max(r1, r2));
  return (num1 * m + num2 * m) / m;
}

/**
 * 浮点数乘法，解决精度问题
 * @param {number} num1 第一个数字
 * @param {number} num2 第二个数字
 * @returns {number} 相乘结果
 */
export function multiply(num1, num2) {
  const m = `${num1}`.split('.')[1]?.length || 0 + `${num2}`.split('.')[1]?.length || 0;
  return Number(`${num1}`.replace('.', '')) * Number(`${num2}`.replace('.', '')) / Math.pow(10, m);
}

/**
 * 浮点数除法，解决精度问题
 * @param {number} num1 被除数
 * @param {number} num2 除数
 * @returns {number} 相除结果
 */
export  function divide(num1, num2) {
  const t1 = `${num1}`.split('.')[1]?.length || 0;
  const t2 = `${num2}`.split('.')[1]?.length || 0;
  const r1 = Number(`${num1}`.replace('.', ''));
  const r2 = Number(`${num2}`.replace('.', ''));
  return (r1 / r2) * Math.pow(10, t2 - t1);
}

/**
 * 浮点数四舍五入
 * @param {number} num 要四舍五入的数字
 * @param {number} decimals 小数位数，默认为2
 * @returns {number} 四舍五入结果
 */
export function round(num, decimals = 2) {
  const m = Math.pow(10, decimals);
  return Math.round(num * m) / m;
}

/**
 * 精确求和
 * @param {Array<number>} numbers 要求和的数字数组
 * @param {number} decimals 小数位数，默认为2
 * @returns {number} 求和结果
 */
export function numberSum(numbers, decimals = 2) {
  if (!Array.isArray(numbers) || numbers.length === 0) return 0;
  
  let result = 0;
  // 使用精确计算方法逐个数相加
  for (let i = 0; i < numbers.length; i++) {
    const num = parseFloat(numbers[i]) || 0;
    result = add(result, num);
  }
  
  // 根据指定的小数位数进行四舍五入
  return round(result, decimals);
}